#include "syscall.h"

int mv;

char buf[200];
int len = 0;

void print(int x) {
	int num = 1;
	int t = x/10;
	int i;
	char a[11];
	while (t) {
		num++;
		t /= 10;
	}
	for(i = 1; i <= num; i++) {
		a[num-i] = (x%10) + '0';
		x /= 10;
	}
	for(i = 0; i < num; i++) {
		buf[len++] = a[i];
	}
/*	Write(a, num, ConsoleOutput); */
}

void prints(char *a) {
	int i;
	for(i = 0; a[i]; i++)
		buf[len++] = a[i];
	if (buf[len-1] == '\n') {
		Write(buf,len,ConsoleOutput);
		len = 0;
	}
}

/* Negative Tests */

void DestroyLockNeg() {
	DestroyLock(100);
}

void AcquireNeg() {
	Acquire(110);
}

void ReleaseNeg() {
	Release(120);
}

void DestroyCVNeg() {
	DestroyCondition(100);
}

void WaitNeg() {
	Wait(1,1);
}

void WaitWithInvalidLock () {
	int cv;
	cv = CreateCondition("cv", 2);
	Wait(cv,1);
}

void SignalNeg() {
	Signal(1,1);
}

void SignalWithInvalidLock () {
	int cv;
	cv = CreateCondition("cv", 2);
	Signal(cv,1);
}

void BroadcastNeg() {
	Broadcast(1,1);
}

void BroadcastWithInvalidLock () {
	int cv;
	cv = CreateCondition("cv", 2);
	Broadcast(cv,1);
}

void DestroyMVNeg () {
	DestroyMonitor(1);
}

void ReadMVNeg() {
	ReadMonitor(1,10);
	
}

void ReadMVOutOfBoundry() {
	int mv;
	mv = CreateMonitor("mv", 1, 3);
	ReadMonitor(mv,10);
	
}

void SetMVNeg() {
	SetMonitor(1,10,100);
}

void SetMVOutOfBoundry() {
	int mv;
	mv = CreateMonitor("mv", 1, 3);
	SetMonitor(mv,10,100);
}


int main() {
	char b[10];
	prints("Which negative test you want to run? (input :a/b/c/d/e/f/g/h/i/j/k/l/m/n/o)\n");
	prints("a: Destroy Lock with invalid Lock ID\n");
	prints("b: Acquire Lock with invalid Lock ID\n");
	prints("c: Release Lock with invalid Lock ID\n");
	prints("d: Destroy CV with invalid CV ID\n");
	prints("e: Wait on CV with invalid CV ID\n");
	prints("f: Wait on CV with invalid Lock ID\n");
	prints("g: Signal on CV with invalid CV ID\n");
	prints("h: Broadcast on CV with invalid Lock ID\n");
	prints("i: Signal on CV with invalid CV ID\n");
	prints("j: Broadcast on CV with invalid Lock ID\n");
	prints("k: Destroy MV with invalid MV ID\n");
	prints("l: Read MV with invalid MV ID\n");
	prints("m: Read MV with invalid index larger than MV size\n");
	prints("n: Set MV with invalid MV ID\n");
	prints("o: Set MV with invalid index larger than MV size\n");
	Read(b,9,ConsoleInput);
	switch(b[0]) {
		case 'a':
		DestroyLockNeg();
		break;
		case 'b':
		AcquireNeg();
		break;
		case 'c':
		ReleaseNeg();
		break;
		case 'd':
		DestroyCVNeg();
		break;
		case 'e':
		WaitNeg();
		break;
		case 'f':
		WaitWithInvalidLock();
		break;
		case 'g':
		SignalNeg();
		break;
		case 'h':
		SignalWithInvalidLock();
		break;
		case 'i':
		BroadcastNeg();
		break;
		case 'j':
		BroadcastWithInvalidLock();
		break;
		case 'k':
		DestroyMVNeg();
		break;
		case 'l':
		ReadMVNeg();
		break;
		case 'm':
		ReadMVOutOfBoundry();
		break;
		case 'n':
		SetMVNeg();
		break;
		case 'o':
		SetMVOutOfBoundry();
		break;
		default:
		prints("Please input from a to o.");
	}
	Exit(0);
}
